<template>
    <div class="json-node">
        <!-- 对象和数组的渲染 -->
        <div v-if="isComplexType" class="json-node-complex">
            <div class="json-node-toggle flex items-center cursor-pointer px-1 rounded" @click="toggleExpanded">
                <span class="json-node-toggle-icon w-4 h-4 flex items-center justify-center text-xs mr-1">
                    <svg v-if="isExpanded" class="w-4 h-4" fill="currentColor" viewBox="0 0 20 20">
                        <path
                            fill-rule="evenodd"
                            d="M5.293 7.293a1 1 0 011.414 0L10 10.586l3.293-3.293a1 1 0 111.414 1.414l-4 4a1 1 0 01-1.414 0l-4-4a1 1 0 010-1.414z"
                            clip-rule="evenodd"
                        />
                    </svg>
                    <svg v-else class="w-4 h-4" fill="currentColor" viewBox="0 0 20 20">
                        <path
                            fill-rule="evenodd"
                            d="M7.293 14.707a1 1 0 010-1.414L10.586 10 7.293 6.707a1 1 0 011.414-1.414l4 4a1 1 0 010 1.414l-4 4a1 1 0 01-1.414 0z"
                            clip-rule="evenodd"
                        />
                    </svg>
                </span>

                <span v-if="!isRoot" class="json-node-toggle-name mr-2">{{ displayName }}:</span>

                <span class="json-node-toggle-bracket">
                    {{ isArray ? '[' : '{' }}
                    <span v-if="!isExpanded" class="json-node-toggle-count ml-1">
                        {{ isArray ? `${itemCount} items` : `${itemCount} properties` }}
                    </span>
                    <span v-if="!isExpanded">{{ isArray ? ']' : '}' }}</span>
                </span>
            </div>

            <!-- 展开状态下的内容 -->
            <div v-if="isExpanded" class="json-node-content ml-4 pl-4 mt-1">
                <template v-if="isArray">
                    <div v-for="(item, index) in data as JsonArray" :key="index" class="json-node-item mb-1">
                        <JsonNode :data="item" :name="index.toString()" />
                    </div>
                </template>
                <template v-else>
                    <div
                        v-for="[key, value] in Object.entries(data as JsonObject)"
                        :key="key"
                        class="json-node-item mb-1"
                    >
                        <JsonNode :data="value" :name="key" />
                    </div>
                </template>
                <div class="json-node-content-closing -ml-4">{{ isArray ? ']' : '}' }}</div>
            </div>
        </div>

        <!-- 基本类型的渲染 -->
        <div v-else class="json-node-simple flex">
            <span v-if="!isRoot" class="json-node-simple-name mr-2">{{ displayName }}:</span>
            <span :class="valueClass">{{ formattedValue }}</span>
        </div>
    </div>
</template>

<script setup lang="ts">
import { ref, computed } from 'vue'

type JsonPrimitive = string | number | boolean | null
type JsonValue = JsonPrimitive | JsonObject | JsonArray
interface JsonObject {
    [key: string]: JsonValue
}
type JsonArray = JsonValue[]

interface Props {
    data: JsonValue
    name: string
    isRoot?: boolean
}

const props = defineProps<Props>()

const isExpanded = ref(true)

const isComplexType = computed(() => {
    return typeof props.data === 'object' && props.data !== null
})

const isArray = computed(() => {
    return Array.isArray(props.data)
})

const itemCount = computed(() => {
    if (isArray.value) {
        return (props.data as JsonArray).length
    }
    return Object.keys(props.data as JsonObject).length
})

const displayName = computed(() => {
    if (isArray.value && /^\d+$/.test(props.name)) {
        return `[${props.name}]`
    }
    return `"${props.name}"`
})

const valueClass = computed(() => {
    const value = props.data

    if (value === null) return 'json-node-simple-value--null'
    if (typeof value === 'string') return 'json-node-simple-value--string'
    if (typeof value === 'number') return 'json-node-simple-value--number'
    if (typeof value === 'boolean') return 'json-node-simple-value--boolean'

    return 'json-node-simple-value--default'
})

const formattedValue = computed(() => {
    const value = props.data

    if (value === null) return 'null'
    if (typeof value === 'string') return `"${value}"`
    if (typeof value === 'boolean') return value.toString()
    if (typeof value === 'number') return value.toString()

    return String(value)
})

const toggleExpanded = () => {
    isExpanded.value = !isExpanded.value
}
</script>

<style lang="scss" scoped>
/* 组件样式已全局导入 */
</style>
